package com.hera.base.web.vaadin.push;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @author cmontes
 *
 */
public class BroadcasterVaadin implements Serializable{

	/**
	 * 
	 */
	private static final long serialVersionUID = -6178215937126770860L;
	
	private static ExecutorService executorService =
	        Executors.newSingleThreadExecutor();
	
	private static Map<String, Map<String, BroadcastVaadinListener>> listeners =
	        new HashMap<String, Map<String, BroadcastVaadinListener>>();
	
	public static synchronized void register(String keyUser, String keySession,
			BroadcastVaadinListener listener) {
		if(!listeners.containsKey(keyUser)){
			listeners.put(keyUser, new HashMap<String, BroadcastVaadinListener>());
		}
		listeners.get(keyUser).put(keySession, listener);
	    listeners.put(keyUser, listeners.get(keyUser));
	}
	    
	public static synchronized void unregisterUser(
	        String keyUser) {
	    listeners.remove(keyUser);
	}
	
	public static synchronized void unregisterSession(
			String keyUser, String keySession) {
	    listeners.get(keyUser).remove(keySession);
	}
		    
	public static synchronized void broadcastAll(
	        final String message) {
		for (final Map.Entry<String, Map<String, BroadcastVaadinListener>> entry : listeners.entrySet()){
			for (final Map.Entry<String, BroadcastVaadinListener> entrysession : entry.getValue().entrySet()){
				
		        executorService.execute(new Runnable() {
		            @Override
		            public void run() {
		            	entrysession.getValue().receiveBroadcast(message);
		            }
		        });
			}
		}
	}
	
	public static synchronized void broadcastAllNotSpecificUser(
			final String keyUser, final String message) {
		for (final Map.Entry<String, Map<String, BroadcastVaadinListener>> entry : listeners.entrySet()){
			if(!keyUser.equalsIgnoreCase(entry.getKey())){
				for (final Map.Entry<String, BroadcastVaadinListener> entrysession : entry.getValue().entrySet()){
		            executorService.execute(new Runnable() {
		                @Override
		                public void run() {
		                	entrysession.getValue().receiveBroadcast(message);
		                }
		            });
				}
			}
		}
	}
	
	public static synchronized void broadcastSpecificKeyUser(
			final String keyUser, final String message) {
		for (final Map.Entry<String, Map<String, BroadcastVaadinListener>> entry : listeners.entrySet()){
			if(keyUser.equalsIgnoreCase(entry.getKey())){
				for (final Map.Entry<String, BroadcastVaadinListener> entrysession : entry.getValue().entrySet()){
		            executorService.execute(new Runnable() {
		                @Override
		                public void run() {
		                	entrysession.getValue().receiveBroadcast(message);
		                }
		            });
				}
			}
		}
	}
	
	public static synchronized void broadcastSpecificKeyUser(
			final String keyUser) {
		for (final Map.Entry<String, Map<String, BroadcastVaadinListener>> entry : listeners.entrySet()){
			if(keyUser.equalsIgnoreCase(entry.getKey())){
				for (final Map.Entry<String, BroadcastVaadinListener> entrysession : entry.getValue().entrySet()){
		            executorService.execute(new Runnable() {
		                @Override
		                public void run() {
		                	entrysession.getValue().receiveBroadcast();
		                }
		            });
				}
			}
		}
	}
	
	public static synchronized void broadcastAll() {
		for (final Map.Entry<String, Map<String, BroadcastVaadinListener>> entry : listeners.entrySet()){
			for (final Map.Entry<String, BroadcastVaadinListener> entrysession : entry.getValue().entrySet()){
				
		        executorService.execute(new Runnable() {
		            @Override
		            public void run() {
		            	entrysession.getValue().receiveBroadcast();
		            }
		        });
			}
		}
	}
}

